<template>
	<view class="vi_swipeCell">
		<view class="vi_swipeCell_box" :style="boxStyle"
			@touchstart="touchstart"
			@touchmove="touchmove"
			@touchend="touchend">
			<view class="vi_swipeCell_left">
				<slot name="left">
					<view class="vi_swipeCell_button" v-for="(item,index) in buttonsL" :key="index">
						<vi-button @click="onClick(item)"
							:type="item.type||'default'"
							:color="item.color"
							:textColor="item.textColor"
							radius=""
							:plain="item.plain"
							borderBox
							:width="item.width||'auto'"
							height="100%"
							:disabled="item.disabled||disabled||readOnly"
							:disabledMsg="item.disabledMsg"
							:readOnly="item.readOnly"
							:readOnlyMsg="item.readOnlyMsg">
							<text class="vi_swipeCell_buttonText">{{item.name}}</text>
						</vi-button>
					</view>
				</slot>
				<view class="vi_swipeCell_leftArr" v-if="setting.useArr&&leftW">
					<vi-style-controller
						control="background"
						:type="leftArrStyleObj.type"
						:color="leftArrStyleObj.color"
						width="100%"
						height="100%"
						:active="!touchActive&&stopLeft==0"></vi-style-controller>
				</view>
			</view>
			<view class="vi_swipeCell_right">
				<slot name="right">
					<view class="vi_swipeCell_button" v-for="(item,index) in buttonsR" :key="index">
						<vi-button @click="onClick(item)"
							:type="item.type||'default'"
							:color="item.color"
							:textColor="item.textColor"
							radius=""
							:plain="item.plain"
							:width="item.width||'auto'"
							height="100%"
							:disabled="item.disabled||disabled||readOnly"
							:disabledMsg="item.disabledMsg"
							:readOnly="item.readOnly"
							:readOnlyMsg="item.readOnlyMsg">
							<text class="vi_swipeCell_buttonText">{{item.name}}</text>
						</vi-button>
					</view>
				</slot>
				<view class="vi_swipeCell_rightArr" v-if="setting.useArr&&rightW">
					<vi-style-controller
						control="background"
						:type="rightArrStyleObj.type"
						:color="rightArrStyleObj.color"
						width="100%"
						height="100%"
						:active="!touchActive&&stopLeft==0"></vi-style-controller>
				</view>
			</view>
			<view class="vi_swipeCell_center">
				<slot></slot>
			</view>
		</view>
	</view>
</template>

<script>
	export default{
		name:"viSwipeCell",
		props:{
			type:{
				type:[String,null],
				default:""
			},
			color:{
				type:[String,null],
				default:""
			},
			leftButtons:{
				type:[Array,Object,null],
				default:()=>[]
			},
			rightButtons:{
				type:[Array,Object,null],
				default:()=>[]
			},
			opened:{
				type:[Boolean,String,null],
				default:false
			},
			useArr:{
				type:[Boolean,null],
				default:null
			},
			//最小高度
			minHeight:{
				type:[String,null],
				String:""
			},
			//滑动触发距离，单位px
			trigger:{
				type:[Number,null],
				default:0
			},
			//禁用滑动，同时禁止props按钮
			disabled:{
				type:[Boolean,null],
				default:false
			},
			//允许滑动，同时禁止props按钮
			readOnly:{
				type:[Boolean,null],
				default:false
			}
		},
		data(){
			return {
				leftW:"",
				rightW:"",
				startPoint:{},
				endPoint:{},
				touchActive:false,
				offsetLeft: 0,		//动态位移
				stopLeft: 0,		//停止位置
				state:"",
			}
		},
		computed:{
			setting(){
				return {
					minHeight: this.$api.isDefined(this.minHeight)? this.minHeight :"2.5em",
					trigger: this.trigger || 20,
					useArr: this.$api.isBoolean(this.useArr)? this.useArr :true,
				}
			},
			buttonsL(){
				let list = this.leftButtons;
				if(list){
					return this.$api.isArray(list)? list :[list]
				}
				return []
			},
			buttonsR(){
				let list = this.rightButtons;
				if(list){
					return this.$api.isArray(list)? list :[list]
				}
				return []
			},
			leftArrStyleObj(){
				let buttons = this.buttonsL,
					button;
				if(buttons.length){
					button = buttons[buttons.length-1];
					return {
						type: button.type || this.type ||"primary",
						color: button.color || this.color ||""
					}
				}
				return {
					type: this.type ||"primary",
					color: this.color ||""
				}
			},
			rightArrStyleObj(){
				let buttons = this.buttonsR,
					button;
				if(buttons.length){
					button = buttons[0];
					return {
						type: button.type || this.type ||"primary",
						color: button.color || this.color ||""
					}
				}
				return {
					type: this.type ||"primary",
					color: this.color ||""
				}
			},
			boxStyle(){
				let res ={
					"transform": `translateX(${this.offsetLeft}px)`
				};
				if(this.setting.minHeight){
					res["min-height"] = this.setting.minHeight
				}
				if(!this.touchActive){
					res["transition"] = ".3s"
				}
				if(this.setting.useArr){
					if(this.leftW){
						res["padding-left"] = "0.25em"
					}
					if(this.rightW){
						res["padding-right"] = "0.25em"
					}
				}
				return this.$api.objToStr(res)
			},
		},
		methods:{
			touchstart(e){
				if(e.touches.length!=1 || this.disabled){
					return
				}
				let point = e.touches[0];
				this.startPoint ={
					x: point.clientX,
					y: point.clientY,
				}
				this.endPoint = this.startPoint;
				this.touchActive =true;
			},
			touchmove(e){
				if(e.touches.length!=1 || this.disabled){
					return
				}
				let point = e.touches[0];
				let diff = point.clientX - this.startPoint.x + this.stopLeft;
				this.endPoint ={
					x: point.clientX,
					y: point.clientY,
				}
				//正数向右
				if(diff>0&&diff>this.leftW){
					diff = this.leftW
				}else if(diff<0&&Math.abs(diff)>this.rightW){
					diff = -this.rightW
				}
				this.offsetLeft = diff;
			},
			touchend(e){
				if(this.disabled){
					return
				}
				this.touchActive =false;
				let diff = this.endPoint.x - this.startPoint.x,
					trigger = this.setting.trigger;
				if(diff>trigger){//右拉
					if(diff+this.stopLeft>trigger){//打开左侧
						this.offsetLeft = this.leftW
					}else{//关闭右侧
						this.offsetLeft = 0
					}
					this.stopLeft = this.offsetLeft;
					this.state = this.stopLeft>0? "left" :"";
				}else if(diff<-trigger){//左拉
					if(diff+this.stopLeft<-trigger){//打开右侧
						this.offsetLeft = -this.rightW
					}else{//关闭左侧
						this.offsetLeft = 0
					}
					this.stopLeft = this.offsetLeft;
					this.state = this.stopLeft<0? "left" :"";
				}else{//无动作
					this.offsetLeft = this.stopLeft
				}
			},
			onClick(item){
				this.$emit("event", item)
			},
			getSize(){
				const query = uni.createSelectorQuery().in(this);
				query.select('.vi_swipeCell_left').boundingClientRect(data => {
					this.leftW = data.width;
					if(this.state=="left"&&data.width){
						this.offsetLeft = this.stopLeft = this.leftW;
					}
				}).exec();
				
				const query1 = uni.createSelectorQuery().in(this);
				query1.select('.vi_swipeCell_right').boundingClientRect(data => {
					this.rightW = data.width;
					if(this.state=="right"&&data.width){
						this.offsetLeft = this.stopLeft = this.rightW;
					}
				}).exec();
			},
			refresh(){
				this.getSize()
			}
		},
		watch:{
			"opened":{
				immediate:true,
				handler(newValue){
					if(["left","right"].includes(newValue)){
						this.state = newValue;
					}else{
						this.state =""
					}
					if(newValue=="left"&&this.leftW){
						this.offsetLeft = this.stopLeft = this.leftW;
					}else if(newValue=="right"&&this.rightW){
						this.offsetLeft = this.stopLeft = this.rightW;
					}
				}
			}
		},
		created(){
			this.$nextTick(()=>{
				this.getSize()
			})
			//监听窗口变化
			uni.onWindowResize(()=>{
				this.getSize();
			})
		},
		destroyed() {
			uni.offWindowResize(()=>{})
		}
	}
</script>

<style lang="scss">
.vi_swipeCell{
	overflow: hidden;
	.vi_swipeCell_box{
		position: relative;
		display: flex;
		align-items: stretch;
	}
	.vi_swipeCell_buttonText{
		padding: 0 0.5em;
	}
	.vi_swipeCell_left,
	.vi_swipeCell_right{
		display: flex;
		align-items: center;
		position: absolute;
		top: 0;
		bottom: 0;
	}
	.vi_swipeCell_left{
		left: 0;
		transform: translateX(-100%);
	}
	.vi_swipeCell_right{
		right: 0;
		transform: translateX(100%);
	}
	.vi_swipeCell_center{
		width: 100%;
	}
	.vi_swipeCell_button{
		height: 100%;
	}
	.vi_swipeCell_leftArr,
	.vi_swipeCell_rightArr{
		position: absolute;
		top: 0;
		bottom: 0;
		width: 0.25em;
	}
	.vi_swipeCell_leftArr{
		right: 0;
		transform: translateX(100%);
	}
	.vi_swipeCell_rightArr{
		left: 0;
		transform: translateX(-100%);
	}
}
</style>